package biolabs.mcl.syntax

class ModelDefinitionAST(
	val name: String,
	val isAbstract: Boolean,
	val typeParams: List[TypeParamAST],
	val params: List[ConstructorParamAST],
	val superTypes: List[SuperTypeSpecAST],
	val explicitParticipations: List[ParticipationAST],
	val containments: List[ContainmentAST],
	val actions: List[PerformedActionAST]
)

case class TypedIdentifierAST(name: String, tpe: MultiTypeAST)

case class ConstructorParamAST(name: String, typeSpec: MultiTypeAST, primary: Boolean)

abstract class TypeParamAST(val name: String)
case class UnboundedTypeParamAST(override val name: String) extends TypeParamAST(name)
case class UpperBoundedTypeParamAST(override val name: String, val bound: MultiTypeAST) extends TypeParamAST(name)

class SingleTypeAST(val id: String, val typeArgs: List[MultiTypeAST])

class MultiTypeAST(val types: List[SingleTypeAST]) {
	if(types.isEmpty)
		throw new IllegalArgumentException("The class::traits list is empty")
}

class SuperTypeSpecAST(
	val typeSpec: SingleTypeAST,
	val initArgs: List[String],
	val timeScale: Option[(String, String)]
)

class ContainerSpecAST(
	val className: String,
	val initArgs: List[String]
)

abstract class ContainmentAST {
	val name: String
	val tpe: MultiTypeAST
	val timeScale: Option[(String, String)]
}

case class SingletonContainmentAST(name: String, tpe: MultiTypeAST, initExpr: String, timeScale: Option[(String, String)]) extends ContainmentAST
case class MultiContainmentAST(name: String, tpe: MultiTypeAST, assoc: List[TypedIdentifierAST], timeScale: Option[(String, String)], containerType: Option[ContainerSpecAST]) extends ContainmentAST

class PerformedActionAST(
	val actionType: SingleTypeAST,
	val initArgs: List[String],
	val actionTimeSpec: Option[String]
)

class DelegateDesignationAST(
	val typeName: String,
	val usedAction: Option[SingleTypeAST]
)

abstract class DelegateCombinationAST {
	val sourceDelegates: List[DelegateDesignationAST]
}
case class SimpleDelegateCombinationAST(sourceDelegate: DelegateDesignationAST) extends DelegateCombinationAST {
	override val sourceDelegates = List(sourceDelegate)
}
case class MultiDelegateCombinationAST(sourceDelegates: List[DelegateDesignationAST], combinator: String) extends DelegateCombinationAST

case class ParticipationAST(action: SingleTypeAST, delegateCombination: DelegateCombinationAST)